package kxcliprovider

import (
	idlprovider "2024-fall-etohlcin3-apigateway/IDLProvider"
	config "2024-fall-etohlcin3-apigateway/config"
	"fmt"
	"time"

	"github.com/cloudwego/kitex/client"
	"github.com/cloudwego/kitex/client/genericclient"
	"github.com/cloudwego/kitex/pkg/connpool"
	"github.com/cloudwego/kitex/pkg/generic"
	"github.com/cloudwego/kitex/pkg/loadbalance"
	"github.com/cloudwego/kitex/pkg/loadbalance/lbcache"
	etcd "github.com/kitex-contrib/registry-etcd"
	//ruleBasedResolver "github.com/kitex-contrib/resolver-rule-based"
)

// svcname : *cli
var gClis = make(map[string]*genericclient.Client)

func GetGenericCli(svcName string) genericclient.Client {

	if gClis[svcName] == nil {
		newCli := CreateGenericCli(svcName)
		gClis[svcName] = &newCli
	}

	return *gClis[svcName]

}

func CreateGenericCli(svcName string) genericclient.Client {
	var opts []client.Option

	opts = append(opts, client.WithLongConnection(connpool.IdleConfig{MinIdlePerAddress: 10,
		MaxIdlePerAddress: 1000}))

	r, _ := etcd.NewEtcdResolver(config.EtcdEndPoints)

	opts = append(opts, client.WithResolver(r))

	// IMPROVEMENTZ: longer time
	opts = append(opts, client.WithLoadBalancer(
		loadbalance.NewWeightedRandomBalancer(),
		&lbcache.Options{
			RefreshInterval: 30 * time.Second,
			ExpireInterval:  60 * time.Second,
		}))

	p, err := generic.NewThriftFileProvider(config.IdlDirPath + "/" + idlprovider.GetIdlPath(svcName))
	fmt.Println(config.IdlDirPath + "/" + idlprovider.GetIdlPath(svcName))

	idlprovider.IdlProviders[svcName] = &p

	if err != nil {
		panic(err)
	}

	g, err := generic.JSONThriftGeneric(p)
	if err != nil {
		panic(err)
	}

	cli, err := genericclient.NewClient(svcName, g, opts...)

	if err != nil {
		panic(err)
	}

	return cli
}

func UpdateGenericCli(svcName string) {
	gClis[svcName] = nil
	newCli := CreateGenericCli(svcName)
	gClis[svcName] = &newCli
}

// var gCliCount = make(map[string]int)
// var gCliPool = make(map[string][10]*genericclient.Client)
// var mutex sync.Mutex

// func GetGenericCliFromCliPool(svcName string) genericclient.Client {

// 	if _, ok := gCliPool[svcName]; !ok {
// 		mutex.Lock()
// 		defer mutex.Unlock()
// 		var arr [10]*genericclient.Client
// 		gCliPool[svcName] = arr
// 		gCliCount[svcName] = 1
// 		var cli genericclient.Client

// 		for i := 0; i < 10; i++ {
// 			var opts []client.Option

// 			opts = append(opts, client.WithLongConnection(connpool.IdleConfig{MinIdlePerAddress: 10,
// 				MaxIdlePerAddress: 1000}))

// 			r, _ := etcd.NewEtcdResolver(etcdEndPoints)

// 			opts = append(opts, client.WithResolver(r))

// 			opts = append(opts, client.WithLoadBalancer(
// 				loadbalance.NewWeightedRandomBalancer(),
// 				&lbcache.Options{
// 					RefreshInterval: 30 * time.Second,
// 					ExpireInterval:  40 * time.Second,
// 				}))

// 			p, err := idlprovider.GetContentProvider(svcName)

// 			idlprovider.IdlProviders[svcName] = p

// 			if err != nil {
// 				panic(err)
// 			}

// 			g, err := generic.JSONThriftGeneric(p)
// 			if err != nil {
// 				panic(err)
// 			}

// 			cli, err = genericclient.NewClient(svcName, g, opts...)

// 			if err != nil {
// 				panic(err)
// 			}
// 			pool := gCliPool[svcName]
// 			pool[i] = &cli
// 			gCliPool[svcName] = pool

// 		}
// 		return cli
// 	}

// 	mutex.Lock()
// 	defer mutex.Unlock()
// 	ret := gCliPool[svcName][gCliCount[svcName]]
// 	gCliCount[svcName] = (gCliCount[svcName] + 1) % 10
// 	return *ret
// }
